package cn.com.mjsoft.framework.persistence.core;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.sql.DataSource;

import org.apache.log4j.Logger;

import cn.com.mjsoft.framework.behavior.Denotation;

import cn.com.mjsoft.framework.persistence.core.support.EntitySqlBridge;
import cn.com.mjsoft.framework.persistence.core.support.MapValueCallback;
import cn.com.mjsoft.framework.persistence.core.support.UpdateState;
import cn.com.mjsoft.framework.persistence.core.support.transform.BeanValueRowTransform;
import cn.com.mjsoft.framework.persistence.core.support.transform.EntityForGetTransform;
import cn.com.mjsoft.framework.persistence.core.support.transform.MapValueRowTransform;
import cn.com.mjsoft.framework.persistence.core.support.transform.SingleObjectRowTransform;
import cn.com.mjsoft.framework.persistence.exception.CannotGetConnectionException;
import cn.com.mjsoft.framework.persistence.exception.DataAccessException;
import cn.com.mjsoft.framework.persistence.exception.NestedTransactionException;
import cn.com.mjsoft.framework.persistence.exception.NotSingleRowException;
import cn.com.mjsoft.framework.persistence.exception.OpenTransactionAndRegisterErrorException;
import cn.com.mjsoft.framework.util.ObjectUtility;
import cn.com.mjsoft.framework.util.StringUtil;

/**
 * 数据持久化引擎。
 * 
 * @author mjsoft
 * 
 */
public final class PersistenceEngine
{
    private final static Logger log = Logger.getLogger( PersistenceEngine.class );

    private boolean showSql = true;

    private static final int SINGLE = 1;

    private static final String GENERATED_KEY = "return_generated_keys";

    private static final String DEFAULT_UPDATE = "jdbc_default_update";

    /**
     * 静态sql缓存
     */
    private static final Map<String, EntitySqlBridge> entitySqlMap = new ConcurrentHashMap<String, EntitySqlBridge>();

    /**
     * 当前使用的数据源
     */
    private DataSource dataSource;

    /**
     * 当前线程的与事务相关的connection资源
     */
    private static final ThreadLocal<Connection> tranConnectionHolder = new ThreadLocal<Connection>();

    /**
     * 当前线程的共享connection资源
     */
    private static final ThreadLocal<Connection> shareConnectionHolder = new ThreadLocal<Connection>();

    /**
     * 当前线程的连接信息资源
     */
    private static final ThreadLocal<TransactionState> threadInfoHolder = new ThreadLocal<TransactionState>();

    /**
     * 自动提交状态
     */
    private static final boolean AUTO_COMMIT = true;

    /**
     * 关闭自动提交状态
     */
    private static final boolean NOT_AUTO_COMMIT = false;

    /**
     * 一次事务完成
     */
    // private static final boolean TRANSACTION_HAS_DONE = true;
    /**
     * 一次事务失败
     */
    private static final boolean TRANSACTION_FAIL = false;

    /**
     * 异常发生标志
     */
    private static final boolean TRANSACTION_ERROR_FLAG = true;

    /**
     * 批处理模式开始
     */
    private static final boolean BATCH_BEGIN = true;

    /**
     * 批处理模式结束
     */
    private static final boolean BATCH_END = false;

    public PersistenceEngine()
    {

    }

    public PersistenceEngine( DataSource dataSource )
    {
        this.dataSource = dataSource;
    }

    public PersistenceEngine( DataSource dataSource, boolean showSql )
    {
        this.dataSource = dataSource;

        this.showSql = showSql;
    }

    /**
     * 设定一个数据源
     * 
     * @param dataSource
     * 
     */
    public void setDataSource( DataSource dataSource )
    {
        this.dataSource = dataSource;
    }

    /**
     * 得到一个新的Connection
     * 
     * @return
     * @throws SQLException
     */
    public Connection openConnection()
    {
        if( null == dataSource )
        {
            throw new CannotGetConnectionException( "数据源不存在" );
        }

        Connection connection;
        try
        {
            connection = dataSource.getConnection();
            if( connection == null )
            {
                throw new CannotGetConnectionException( "当前无法从当前系统环境获取连接" );
            }
        }
        catch ( SQLException e )
        {
            log.error( e );
            throw new DataAccessException( e );
        }
        return connection;
    }

    /**
     * 执行查询sql,由指定的RowMapper进行结果转换
     * 
     * @param sql
     * @param args
     * @param rowMapper
     * @return
     * @throws DataAccessException
     */
    @SuppressWarnings( "unchecked" )
    public List query( String sql, Object[] args, RowTransform rowMapper )
        throws DataAccessException
    {

        if( rowMapper == null )
        {
            throw new DataAccessException( "没有提供RowMapper" );
        }

        TransactionState txState = ( TransactionState ) threadInfoHolder.get();

        boolean isTxMode = ( txState != null ) ? true : false;

        boolean isShareMode = false;

        log.debug( "当前查询事务模式 ： " + ( isTxMode ? "[Transaction]" : "[autoCommit]" ) );

        Connection connection = null;

        if( !isTxMode )
        {
            connection = ( Connection ) shareConnectionHolder.get();

            if( connection == null )
            {
                log.debug( "当前查询操作所使用连接非线程共享" );
                connection = openConnection();
            }
            else
            {
                isShareMode = true;
                log.debug( "当前查询操作将使用线程共享连接" );
            }
        }

        if( StringUtil.isStringNull( sql ) )
        {
            throw new IllegalArgumentException( "sql语句为空" );
        }

        String querySql = sql.trim();

        if( showSql )
        {
            log.info( "[SYSTEM MySqlPersistenceEngine 执行查询SQL]" + querySql );
        }

        StringBuffer buf = new StringBuffer( "(" );
        if( args != null )
        {
            for ( int i = 0; i < args.length; i++ )
            {
                buf.append( args[i] );
                buf.append( ", " );
            }
        }
        buf.append( ")" );

        if( showSql )
        {
            log.info( "[参数]" + buf.toString() );
        }

        List results = new ArrayList();// 最终的结果

        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try
        {
            if( isTxMode )
            {
                preparedStatement = ( PreparedStatement ) txState.getTransactionModeStmt().get(
                    querySql );

                if( preparedStatement == null )
                {
                    log.info( "当前将注册一个新的查询, [SQL] : " + querySql );
                    preparedStatement = getConnectionInTransactionScene().prepareStatement(
                        querySql );
                    txState.getTransactionModeStmt().put( querySql, preparedStatement );
                }

                /**
                 * 设定当前sql语句所有的参数
                 */
                if( args != null )
                {
                    for ( int i = 0; i < args.length; i++ )
                    {
                        JdbcInstrument.setPreparedStatementParameterValue( preparedStatement,
                            i + 1, args[i] );
                    }
                }

                resultSet = preparedStatement.executeQuery();

                while ( resultSet.next() )
                {
                    results.add( rowMapper.convertRow( resultSet, resultSet.getRow() ) );
                }
                JdbcInstrument.closeResultSet( resultSet );
            }
            else
            {
                if( connection == null )
                {
                    log.error( "当前QUERY操作无法处当前系统环境获取连接" );
                    throw new CannotGetConnectionException( "当前查询操作无法处当前系统环境获取连接" );
                }
                preparedStatement = connection.prepareStatement( querySql );
                /**
                 * 设定当前sql语句所有的参数
                 */
                if( args != null )
                {
                    for ( int i = 0; i < args.length; i++ )
                    {
                        JdbcInstrument.setPreparedStatementParameterValue( preparedStatement,
                            i + 1, args[i] );
                    }
                }

                resultSet = preparedStatement.executeQuery();

                while ( resultSet.next() )
                {
                    results.add( rowMapper.convertRow( resultSet, resultSet.getRow() ) );
                }
                JdbcInstrument.closeResultSet( resultSet );
                resultSet = null;
            }

        }
        catch ( Exception e )
        {
            JdbcInstrument.closeResultSet( resultSet );
            JdbcInstrument.closeStatement( preparedStatement );
            /**
             * 共享模式下在发生异常情况下可以关闭当前连接
             */
            if( !isTxMode )
            {
                JdbcInstrument.closeConnection( connection );
                connection = null;
            }
            else
            // 事务模式下
            {
                txState.setTransactionOver( TRANSACTION_FAIL );
            }
            log.debug( "释放JDBC资源成功" );

            if( e instanceof SQLException )
            {
                SQLException sEx = ( SQLException ) e;
                log.error( "SQL State : " + sEx.getSQLState() );
                log.error( "SQL ErrorCode : " + sEx.getErrorCode() );
                log.error( "SQL异常 : ", e );

            }

            if( e instanceof DataAccessException )
            {
                DataAccessException daEx = ( DataAccessException ) e;
                throw daEx;
            }
            throw new DataAccessException( " 查询发生Exception : ", e );
        }
        finally
        {
            JdbcInstrument.closeResultSet( resultSet );
            /*
             * 在一次数据库操作完成后，如处在事务模式下或share模式下，Connection都不能关闭
             */
            if( !isTxMode && !isShareMode )
            {
                JdbcInstrument.closeStatement( preparedStatement );
                JdbcInstrument.closeConnection( connection );
                log.info( "当前查询操作后释放Connection资源" );
            }
        }

        return results;

    }

    /**
     * 执行查询sql,由指定的RowMapper进行
     * 
     * @param sql
     * @param rowMapper
     * @return
     * @throws DataAccessException
     */
    public List query( String sql, RowTransform rowMapper ) throws DataAccessException
    {
        return query( sql, null, rowMapper );
    }

    /**
     * 执行指定的sql，返回一个对象,如果返回多个对象(多行记录),将抛出异常
     * 
     * @param sql
     * @param args
     * @param rowMapper
     * @return
     * @throws DataAccessException
     */
    public Object querySingleRow( String sql, Object[] args, RowTransform rowMapper )
        throws DataAccessException
    {
        List results = query( sql, args, rowMapper );

        if( results.size() > SINGLE )
        {
            throw new NotSingleRowException( "返回了多行数据" );
        }

        return ( results.size() == 0 ) ? null : results.get( 0 );
    }

    /**
     * 执行指定的sql，返回一个对象,如果返回多个对象(多行记录),将抛出异常
     * 
     * @param sql
     * @param rowMapper
     * @return
     * @throws DataAccessException
     */
    public Object querySingleRow( String sql, RowTransform rowMapper ) throws DataAccessException
    {
        return querySingleRow( sql, null, rowMapper );
    }

    /**
     * 执行指定的sql，返回一个组装好的Bean对象,如果返回多个对象,将抛出异常
     * 
     * @param sql
     * @param args
     * @return
     * @throws DataAccessException
     */
    public Object querySingleObject( String sql, Object[] args ) throws DataAccessException
    {
        return querySingleRow( sql, args, new SingleObjectRowTransform() );
    }

    /**
     * 执行指定的sql，返回一个组装好的Bean对象,如果返回多个对象,将抛出异常
     * 
     * @param sql
     * @param args
     * @param type
     * @return
     * @throws DataAccessException
     */
    public Object querySingleObject( String sql, Object[] args, Class type )
        throws DataAccessException
    {
        return querySingleRow( sql, args, new SingleObjectRowTransform( type ) );
    }

    /**
     * 执行指定的sql，返回一个组装好的Bean对象,如果返回多个对象,将抛出异常
     * 
     * @param sql
     * @param type
     * @return
     * @throws DataAccessException
     */
    public Object querySingleObject( String sql, Class type ) throws DataAccessException
    {
        return querySingleObject( sql, null, type );
    }

    /**
     * 执行指定的sql，返回一个组装好的Bean对象,如果返回多个对象,将抛出异常
     * 
     * @param sql
     * @return
     */
    public Object querySingleObject( String sql )
    {
        return querySingleObject( sql, null, null );
    }

    /**
     * 执行指定的sql，返回一个List,如果每个数据结果非单列,将抛出异常
     * 
     * @param sql
     * @param args
     * @param type
     * @return
     * @throws DataAccessException
     */
    public List querySingleCloumn( String sql, Object[] args, Class type )
        throws DataAccessException
    {
        return query( sql, args, new SingleObjectRowTransform( type ) );
    }

    /**
     * 执行指定的sql，返回一个List,如果每个数据结果非单列,将抛出异常
     * 
     * @param sql
     * @param args
     * @return
     * @throws DataAccessException
     */
    public List querySingleCloumn( String sql, Object[] args ) throws DataAccessException
    {
        return querySingleCloumn( sql, args, null );
    }

    /**
     * 执行指定的sql，返回一个List,如果每个数据结果非单列,将抛出异常
     * 
     * @param sql
     * @param type
     * @return
     */
    public List querySingleCloumn( String sql, Class type )
    {
        return querySingleCloumn( sql, null, type );
    }

    /**
     * 执行指定的sql，返回一个List,如果每个数据结果非单列,将抛出异常
     * 
     * @param sql
     * @return
     */
    public List querySingleCloumn( String sql )
    {
        return querySingleCloumn( sql, null, null );
    }

    /**
     * 执行指定的sql，返回一个反映了结果集的map
     * 
     * @param sql
     * @return
     * @throws DataAccessException
     * 
     */
    public List queryResultMap( String sql ) throws DataAccessException
    {
        return query( sql, null, new MapValueRowTransform() );
    }

    /**
     * 执行指定的sql，返回包含了反映查询结果集的map
     * 
     * @param sql
     * @return List 每个元素为一个Map,映射了表的每一行数据
     * @throws DataAccessException
     * 
     */
    public List queryResultMap( String sql, Object[] args ) throws DataAccessException
    {
        return query( sql, args, new MapValueRowTransform() );
    }

    /**
     * 执行指定的sql，返回包含了反映查询结果集的map,通过最后的callback接口对将返回使用的数据进行处理
     * 
     * @param sql
     * @param callback将在数据返回前对数据进行处理的callback
     * @return List 每个元素为一个Map,映射了表的每一行数据
     * @throws DataAccessException
     * 
     */
    public List queryResultMap( String sql, MapValueCallback callback ) throws DataAccessException
    {
        return query( sql, null, new MapValueRowTransform( callback ) );
    }

    /**
     * 执行指定的sql，返回包含了反映查询结果集的map,通过最后的callback接口对将返回使用的数据进行处理
     * 
     * @param sql
     * @param callback将在数据返回前对数据进行处理的callback
     * @return List 每个元素为一个Map,映射了表的每一行数据
     * @throws DataAccessException
     * 
     */
    public List queryResultMap( String sql, Object[] args, MapValueCallback callback )
        throws DataAccessException
    {
        return query( sql, args, new MapValueRowTransform( callback ) );
    }

    /**
     * 执行指定的sql，返回一个Bean的list,每个bean对应一行sql返回结果
     * 
     * @param sql
     * 
     * @param clazz Bean的Class
     * @return List 指定类型的bean的List,bean的字段名称和sql返回字段名称相同
     * @throws DataAccessException
     */
    public List queryBeanList( String sql, Class clazz ) throws DataAccessException
    {
        return query( sql, new BeanValueRowTransform( clazz ) );
    }

    /**
     * 执行指定的sql，返回一个Bean的list,每个bean对应一行sql返回结果
     * 
     * @param sql
     * 
     * @param clazz Bean的Class
     * @return List 指定类型的bean的List,bean的字段名称和sql返回字段名称相同
     * @throws DataAccessException
     */
    public List queryBeanList( String sql, Object[] args, Class clazz ) throws DataAccessException
    {
        return query( sql, args, new BeanValueRowTransform( clazz ) );
    }

    /**
     * 执行指定的sql，返回唯一一个反映了结果集的map,如果结果非一行,将抛出异常
     * 
     * @param sql
     * @param args sql参数
     * @return Map 唯一的一个结果Map,map中每个数据代表对应的列
     * @throws DataAccessException
     * 
     */
    public Map querySingleResultMap( String sql, Object[] args ) throws DataAccessException
    {
        List result = query( sql, args, new MapValueRowTransform() );

        if( result.size() > SINGLE )
        {
            throw new NotSingleRowException( "返回了多行数据" );
        }

        return ( Map ) ( ( result.size() == 0 ) ? new LinkedHashMap() : result.get( 0 ) );
    }

    /**
     * 执行指定的sql，返回唯一一个反映了结果集的map,如果结果非一行,将抛出异常,通过callback对将返回数据进处理
     * 
     * @param sql
     * @param args sql参数
     * @param callback 将对将返回的数据进行处理
     * @return Map 唯一的一个结果Map,map中每个数据代表对应的列
     * @throws DataAccessException
     * 
     */
    public Map querySingleResultMap( String sql, Object[] args, MapValueCallback callback )
        throws DataAccessException
    {
        List result = query( sql, args, new MapValueRowTransform( callback ) );

        if( result.size() > SINGLE )
        {
            throw new NotSingleRowException( "返回了多行数据" );
        }

        return ( Map ) ( ( result.size() == 0 ) ? new LinkedHashMap() : result.get( 0 ) );
    }

    /**
     * 执行指定的sql，返回唯一一个Bean,如果结果非一行,将抛出异常
     * 
     * @param sql
     * @param args
     * @param clazz
     * @return Bean 唯一的指定类型的bean,bean的字段名称和sql返回字段名称相同
     * @throws DataAccessException
     */
    public Object querySingleBean( String sql, Object[] args, Class clazz )
        throws DataAccessException
    {
        List result = query( sql, args, new BeanValueRowTransform( clazz ) );

        if( result.size() > SINGLE )
        {
            throw new NotSingleRowException( "返回了多行数据" );
        }

        return ( ( result.size() == 0 ) ? null : result.get( 0 ) );
    }

    /**
     * 执行指定的sql，返回唯一一个反映了结果集的map,如果结果非一行,将抛出异常
     * 
     * @param sql
     * @return Map 唯一的一个结果Map,map中每个数据代表对应的列
     * @throws DataAccessException
     * 
     */
    public Map querySingleResultMap( String sql ) throws DataAccessException
    {
        return querySingleResultMap( sql, null );
    }

    /**
     * 执行指定的sql，返回唯一一个Bean,如果结果非一行,将抛出异常
     * 
     * @param sql
     * 
     * @param clazz
     * @return Bean 唯一的指定类型的bean,bean的字段名称和sql返回字段名称相同
     * @throws DataAccessException
     */
    public Object querySingleBean( String sql, Class clazz ) throws DataAccessException
    {
        List result = query( sql, new BeanValueRowTransform( clazz ) );

        if( result.size() > SINGLE )
        {
            throw new NotSingleRowException( "返回了多行数据" );
        }

        return ( ( result.size() == 0 ) ? null : result.get( 0 ) );
    }

    /**
     * @deprecated 根据提供的Pojo类型和唯一标识符取得数据 <br/>
     *             此方法不再使用,由query( Class beanClass, Object id 替代
     * 
     * @param targetClazz
     * @param id
     * @return
     */
    public Object get( Class targetClazz, Object id )
    {
        log.info( "待执行get操作的目标类型 ：" + targetClazz.getName() + " ,唯一标识Id ：" + id );

        return querySingleRow( getEntitySql( targetClazz ).getSelectSql(), new Object[] { id },
            new EntityForGetTransform( targetClazz ) );
    }

    /**
     * 根据提供的Pojo类型和唯一标识符取得Pojo
     * 
     * @param pojoClass 必须为TableInfomationProvider的VO类型
     * @param id
     * @return Bean对象
     */
    public Object query( Class beanClass, Object id )
    {
        return querySingleBean( getEntitySql( beanClass ).getSelectSql(), new Object[] { id },
            beanClass );
    }

    /**
     * ORM方法，将传入的Pojo对象数据存入到对应的表中
     * 
     * @param object 要进行持久化的Pojo对象
     * @return int 如果插入了一行数据，将返回标志1，0表示没有插入
     */
    public UpdateState save( Object object )
    {
        log.info( "将执行映射save操作的对象 ：" + object );

        if( object == null )
        {
            return new UpdateState();
        }

        EntitySqlBridge entitySql = getEntitySql( object.getClass() );

        Object[] params = getAllInsertParamValue( object, entitySql.getInsertParamCount() );
        return insert( entitySql.getInsertSql(), params );
    }

    /**
     * ORM方法，将指定VO对象中每字段值更新到对应表中。
     * 
     * @param pojo
     * @return
     */
    public UpdateState update( Object pojo )
    {
        log.info( "待映射更新操作的Pojo对象 ：" + pojo );

        if( pojo == null )
        {
            return new UpdateState();
        }

        EntitySqlBridge entitySql = getEntitySql( pojo.getClass() );

        Object[] params = getAllUpdateParamValue( pojo, entitySql.getUpdateParamCount() );

        return JdbcUpdate( entitySql.getUpdateSql(), params, new Denotation( DEFAULT_UPDATE ) );
    }

    /**
     * ORM方法，删除给予pojo对应行的信息
     * 
     * @param pojo pojo对象
     * @return 返回1表示更新了数据
     */
    public UpdateState delete( Object pojo )
    {
        log.info( "待映射删除操作的Pojo对象 ：" + pojo );

        if( pojo == null )
        {
            return new UpdateState();
        }

        return delete( pojo.getClass(), getIdParamValue( pojo ) );

    }

    /**
     * ORM方法， 删除给予pojo对应行的信息，
     * 
     * @param clazz 目标Pojo类型
     * @param idValue 主键值
     * @return 返回1表示更新了数据
     */
    public UpdateState delete( Class clazz, Object idValue )
    {
        log.info( "待映射删除操作的Pojo类型 ：" + clazz + ", ID : " + idValue );

        if( clazz == null )
        {
            return new UpdateState();
        }

        EntitySqlBridge entitySql = getEntitySql( clazz );

        return JdbcUpdate( entitySql.getDeleteSql(), new Object[] { idValue }, new Denotation(
            DEFAULT_UPDATE ) );
    }

    /**
     * 根据传入的sql更新数据库
     * 
     * @param sql 执行的sql语句
     * @return 更新了多少行数据
     * @throws DataAccessException
     */
    public UpdateState update( String sql ) throws DataAccessException
    {
        return JdbcUpdate( sql, null, new Denotation( DEFAULT_UPDATE ) );
    }

    /**
     * 返回自增加Key的insert方法，返回key的行为依赖于各实际数据库
     * 
     * @param sql
     * @param args
     * @return
     */
    public UpdateState insert( String sql, Object[] args )
    {
        return JdbcUpdate( sql, args, new Denotation( GENERATED_KEY ) );
    }

    /**
     * 返回自增加Key的insert方法，返回key的行为依赖于各实际数据库,Bean参数模式
     * 
     * @param sql
     * @param bean
     * @return
     */
    public UpdateState insert( String sql, Object bean )
    {
        Object[] args = JdbcInstrument.disposeSqlParamArgs( sql, bean );

        return JdbcUpdate( sql, args, new Denotation( GENERATED_KEY ) );
    }

    /**
     * 返回自增加Key的insert方法，返回key的行为依赖于各实际数据库,Map参数模式
     * 
     * @param sql
     * @param paramMap
     * @return
     */
    public UpdateState insert( String sql, Map<String, Object> paramMap )
    {
        Object[] args = JdbcInstrument.disposeSqlParamArgsForMap( sql, paramMap );

        return JdbcUpdate( sql, args, new Denotation( GENERATED_KEY ) );
    }

    /**
     * 执行数据改动sql。
     * 
     * @param sql
     * @param args
     * @return
     */
    public UpdateState update( String sql, Object[] args )
    {
        return JdbcUpdate( sql, args, new Denotation( DEFAULT_UPDATE ) );
    }

    /**
     * 执行更改sql,自动组装参数,bean模式
     * 
     * @param sql
     * @param args
     * @return
     */
    public UpdateState update( String sql, Object bean )
    {
        Object[] args = JdbcInstrument.disposeSqlParamArgs( sql, bean );

        return JdbcUpdate( sql, args, new Denotation( DEFAULT_UPDATE ) );
    }

    /**
     * 执行更改sql,自动组装参数,Map模式
     * 
     * @param sql
     * @param args
     * @return
     */
    public UpdateState update( String sql, Map paramMap )
    {
        Object[] args = JdbcInstrument.disposeSqlParamArgsForMap( sql, paramMap );

        return JdbcUpdate( sql, args, new Denotation( DEFAULT_UPDATE ) );
    }

    /**
     * 根据传入的sql以及相关参数更新数据库数据状态
     * 
     * @param sql 执行的sql语句
     * @param args sql参数数组
     * @return 更新了多少行数据
     * @throws DataAccessException
     */
    private UpdateState JdbcUpdate( String sql, Object[] args, Denotation deno )
        throws DataAccessException
    {
        TransactionState txState = ( TransactionState ) threadInfoHolder.get();

        boolean isTxMode = ( txState != null ) ? true : false;

        log.debug( "当前update模式 ： " + ( isTxMode ? "[Transaction]" : "[AutoCommit]" ) );

        Connection connection = null;
        boolean isShareMode = false;

        /**
         * 非事务情况下需要重新打开一个Connection对象，而共享模式情况取得的是上下文环境下的Connection
         */
        if( !isTxMode )
        {
            connection = ( Connection ) shareConnectionHolder.get();

            if( connection == null )
            {
                log.info( "当前更新操作所使用连接非线程共享" );
                connection = openConnection();
            }
            else
            {
                isShareMode = true;
                log.info( "当前更新操作将使用线程共享连接" );
            }
        }

        if( StringUtil.isStringNull( sql ) )
        {
            throw new IllegalArgumentException( "sql语句为空" );
        }

        String updateSql = sql.trim();

        if( showSql )
        {
            log.info( "[SYSTEM MySqlPersistenceEngine 执行更新SQL]" + updateSql );
        }

        StringBuffer buf = new StringBuffer( "(" );
        if( args != null )
        {
            for ( int i = 0; i < args.length; i++ )
            {
                if( args[i] != null && args[i].toString().length() > 30 )
                {
                    buf.append( StringUtil.subString( args[i].toString(), 0, 30 ) + "..." );
                }
                else
                {
                    buf.append( args[i] );
                }
                buf.append( ", " );
            }
        }
        buf.append( ")" );

        if( showSql )
        {
            log.info( "[参数]" + buf.toString() );
        }

        // 记录一次Update操作后的状态
        UpdateState updateState = new UpdateState();
        PreparedStatement preparedStatement = null;

        try
        {
            // 在事务模式下尝试批处理执行
            if( isTxMode )
            {
                if( txState.isBatchUpdateMode() )
                {
                    /**
                     * 尝试得到重复的sql对应的preparedStatement，如果有的话只需要进行addBatch
                     */
                    preparedStatement = ( PreparedStatement ) txState.getBatchModeStmt().get(
                        updateSql );

                    if( preparedStatement == null )// 首次碰到的sql，一个新的batch
                    {
                        if( showSql )
                        {
                            log.info( "当前将注册一个新的batch, [SQL] : " + updateSql );
                        }

                        preparedStatement = getConnectionInTransactionScene().prepareStatement(
                            updateSql );
                        txState.getBatchModeStmt().put( updateSql, preparedStatement );
                    }

                    if( args != null )
                    {
                        for ( int i = 0; i < args.length; i++ )
                        {
                            JdbcInstrument.setPreparedStatementParameterValue( preparedStatement,
                                i + 1, args[i] );
                        }
                    }

                    preparedStatement.addBatch();
                    log.info( "[批处理更新模式] ... 加入到Batch ..." );
                }
                else
                // 一般的事务更新行为
                {
                    ResultSet keyResultSet = null;

                    if( deno.getDenotation().equals( GENERATED_KEY ) )
                    {
                        log.info( "进入返回key更新模式" );

                        if( txState.getTransactionKeyModeStmt() == null )
                        {
                            txState.setTransactionKeyModeStmt( new HashMap() );
                        }

                        preparedStatement = ( PreparedStatement ) txState
                            .getTransactionKeyModeStmt().get( updateSql );

                        if( preparedStatement == null )
                        {
                            log.info( "当前将注册一个新的Key模式数据更新Statement, [SQL] : " + updateSql );
                            preparedStatement = getConnectionInTransactionScene().prepareStatement(
                                updateSql, Statement.RETURN_GENERATED_KEYS );
                            txState.getTransactionKeyModeStmt().put( updateSql, preparedStatement );
                        }

                    }
                    else
                    {
                        preparedStatement = ( PreparedStatement ) txState.getTransactionModeStmt()
                            .get( updateSql );
                        if( preparedStatement == null )
                        {
                            log.info( "当前将注册一个新的数据更新Statement, [SQL] : " + updateSql );
                            preparedStatement = getConnectionInTransactionScene().prepareStatement(
                                updateSql );
                            txState.getTransactionModeStmt().put( updateSql, preparedStatement );
                        }

                    }

                    if( args != null )
                    {
                        for ( int i = 0; i < args.length; i++ )
                        {
                            JdbcInstrument.setPreparedStatementParameterValue( preparedStatement,
                                i + 1, args[i] );
                        }
                    }

                    if( deno.getDenotation().equals( GENERATED_KEY ) )
                    {
                        // 执行update
                        updateState.setRow( preparedStatement.executeUpdate() );
                        // 返回key
                        keyResultSet = preparedStatement.getGeneratedKeys();

                        if( keyResultSet.next() )
                        {
                            updateState.setKey( keyResultSet.getLong( 1 ) );
                        }
                    }
                    else
                    {
                        updateState.setRow( preparedStatement.executeUpdate() );
                    }
                }
            }
            else
            {
                if( connection == null )
                {
                    log.error( "当前UPDATE操作无法处当前系统环境获取连接" );
                    throw new CannotGetConnectionException( "当前查询操作无法处当前系统环境获取连接" );
                }

                ResultSet keyResultSet = null;

                if( deno.getDenotation().equals( GENERATED_KEY ) )
                {
                    preparedStatement = connection.prepareStatement( updateSql,
                        Statement.RETURN_GENERATED_KEYS );
                }
                else
                {
                    preparedStatement = connection.prepareStatement( updateSql );
                }

                if( args != null )
                {
                    for ( int i = 0; i < args.length; i++ )
                    {
                        JdbcInstrument.setPreparedStatementParameterValue( preparedStatement,
                            i + 1, args[i] );
                    }
                }

                if( deno.getDenotation().equals( GENERATED_KEY ) )
                {
                    // 执行update
                    updateState.setRow( preparedStatement.executeUpdate() );
                    // 返回key
                    keyResultSet = preparedStatement.getGeneratedKeys();

                    if( keyResultSet.next() )
                    {
                        updateState.setKey( keyResultSet.getLong( 1 ) );
                    }
                }
                else
                {
                    updateState.setRow( preparedStatement.executeUpdate() );
                }
            }
        }
        catch ( Exception e )
        {
            /**
             * 事务模式下，发生异常在这里不可立即关闭Connection,但其他模式可以，因为<br>
             * 其他模式不需要回滚。
             */
            if( !isTxMode )
            {
                JdbcInstrument.closeConnection( connection );
                connection = null;
                log.info( "<异常处理> 释放Connection资源成功" );
            }
            else
            {
                txState.setTransactionOver( TRANSACTION_FAIL );
            }

            if( e instanceof SQLException )
            {
                SQLException sEx = ( SQLException ) e;
                log.error( "SQL State : " + sEx.getSQLState() );
                log.error( "SQL ErrorCode : " + sEx.getErrorCode() );
                log.error( "SQL异常 : ", e );

            }

            if( e instanceof DataAccessException )
            {
                DataAccessException daEx = ( DataAccessException ) e;
                throw daEx;
            }
            throw new DataAccessException( "Exception : ", e );
        }
        finally
        {
            // if (isTxMode)// 事务模式下
            // {
            // // 且不是批处理模式
            // if (!txState.isBatchUpdateMode()) {
            // // 直接关闭Statement
            // JdbcInstrument.closeStatement(preparedStatement);
            // log.info("[update 事务模式] 释放Statement资源...");
            // }
            // } else
            // if (isShareMode)// 共享模式，只关闭Statement资源
            // {
            // JdbcInstrument.closeStatement(preparedStatement);
            // log.info("<共享模式> 关闭Statement资源");
            // } else
            // 普通模式，关闭所有
            if( !( isShareMode || isTxMode ) )
            {
                JdbcInstrument.closeStatement( preparedStatement );
                JdbcInstrument.closeConnection( connection );
                log.info( "<普通模式> 关闭所有JDBC资源" );
            }
        }
        return updateState;
    }

    /**
     * 开启一个事务，此方法会对其目标connection进行判断，如果其已经有事务状态<br>
     * （嵌套或线程控制错误），会拒绝生成事务状态对象开启事务
     * 
     */

    public void beginTransaction()
    {
        Connection connection = ( Connection ) shareConnectionHolder.get();

        /**
         * 启用线程共享后，不能够再使用事务提交模式
         */
        if( connection != null )
        {
            JdbcInstrument.closeConnection( connection );
            shareConnectionHolder.set( null );
            throw new DataAccessException( "事务启动失败错误,当前线程已存在共享连接并处于自动提交模式" );
        }

        connection = ( Connection ) tranConnectionHolder.get();

        try
        {
            /**
             * 如果当前线程容器已经有了Connection,那么意味着当前在重复启动事务,<br>
             * 或有其他情况导致当前处理线程有未知connection
             */

            if( connection != null )
            {
                if( JdbcInstrument.closeConnection( connection ) )
                {
                    connection = null;
                }
                tranConnectionHolder.set( null );
                threadInfoHolder.set( null );

                throw new NestedTransactionException( "事务启动错误，发生了事务嵌套,此原因由重复启动事务或线程中某次事务状态对象没有被清理" );
            }

            if( null == dataSource )
            {
                throw new CannotGetConnectionException( "数据源不存在,数据源或许没有正常初始化或已经失效" );
            }

            connection = dataSource.getConnection(); // 从数据源获取connection

            connection.setAutoCommit( NOT_AUTO_COMMIT );// 自动提交模式关闭

            /**
             * 共享Connection
             */
            tranConnectionHolder.set( connection );

            /**
             * 增加本次事务标识
             */
            TransactionState txState = new TransactionState();
            // 默认必有一般性的数据库操作事务存在，在此设定
            txState.setTransactionModeStmt( new HashMap() );
            threadInfoHolder.set( txState );
            log.info( "事务状态 [ --- 成功开启 --- ]" );

        }
        catch ( Exception e )
        {
            if( JdbcInstrument.closeConnection( connection ) )
            {
                connection = null;
            }

            tranConnectionHolder.set( null );
            threadInfoHolder.set( null );// 事务标识剥离

            if( e instanceof SQLException )
            {
                SQLException sEx = ( SQLException ) e;
                log.error( "SQL State : " + sEx.getSQLState() );
                log.error( "SQL ErrorCode : " + sEx.getErrorCode() );
                log.error( "SQL异常 : ", e );

            }

            if( e instanceof DataAccessException )
            {
                DataAccessException daEx = ( DataAccessException ) e;
                throw daEx;
            }

            throw new OpenTransactionAndRegisterErrorException( "事务开启动作失败 : ", e );
        }

    }

    /**
     * 将当前事务中包含的所有数据操作提交给数据库
     * 
     * @throws DataAccessException
     * 
     */
    public void commit() throws DataAccessException
    {

        Connection connection = getConnectionInTransactionScene();
        TransactionState txState = getTransactionState();

        try
        {
            // 尝试提交事务
            connection.commit();

            /**
             * 立即清理数据库各种资源
             */
            Map txStmtMap = txState.getTransactionModeStmt();
            if( txStmtMap != null )
            {
                /**
                 * 关闭一般事更新务statement
                 */
                clearAllTxStmt( txStmtMap );
                txState.setTransactionModeStmt( null );
            }

            Map txKeyStmtMap = txState.getTransactionKeyModeStmt();
            if( txKeyStmtMap != null )
            {
                /**
                 * 关闭一般事更新务statement
                 */
                clearAllTxStmt( txKeyStmtMap );
                txState.setTransactionKeyModeStmt( null );
            }

            Map pStmtMap = txState.getBatchModeStmt();
            if( pStmtMap != null )
            {
                /**
                 * 关闭批处理statement
                 */
                clearAllTxStmt( pStmtMap );
                txState.setBatchModeStmt( null );
            }

            /**
             * 对于事务模式下，事物结束后需要回到自动提交模式,且记,<br>
             * 这是不发生任何异常的情况下,做这些恢复 出现异常另处理
             */
            setToAutoCommitState( connection );
            JdbcInstrument.closeConnection( connection );
            log.info( "[commit] ：数据库资源释放......" );

            /**
             * 清除线程变量资源一定要放在最后.保证前面不出现任何异常,出现异常不可清除动作
             */
            tranConnectionHolder.set( null );
            threadInfoHolder.set( null );

            log.info( "事务状态 [ --- 提交 --- ]" );
        }
        catch ( Exception e )
        {
            /**
             * 任何异常将导致本次事务不结束,告之endTransaction做相关处理
             */
            txState.setTransactionOver( TRANSACTION_FAIL );
            txState.setExceptionOccur( TRANSACTION_ERROR_FLAG );

            if( e instanceof SQLException )
            {
                SQLException sEx = ( SQLException ) e;
                log.error( "SQL State : " + sEx.getSQLState() );
                log.error( "SQL ErrorCode : " + sEx.getErrorCode() );
                log.error( "SQL异常 : ", e );

            }

            if( e instanceof DataAccessException )
            {
                DataAccessException daEx = ( DataAccessException ) e;
                throw daEx;
            }
            throw new DataAccessException( "Exception : ", e );
        }
        /**
         * 异常处理中如果发生异常无法正常提交，Connectio也不能在关闭，<br>
         * 因为后面仍然需要这个连接来进行处理回滚等情况
         */
    }

    /**
     * 回滚数据行为
     * 
     * @throws DataAccessException
     */
    @SuppressWarnings( "unchecked" )
    public void rollback() throws DataAccessException
    {
        log.info( "事务状态 [ --- 开始回滚 --- ]" );

        Connection connection = getConnectionInTransactionScene();

        try
        {
            connection.rollback();// 尝试回滚
            /**
             * 回滚成功后，释放相关资源
             */

            log.debug( "回滚成功......" );
        }

        catch ( Exception e )
        {
            if( e instanceof SQLException )
            {
                SQLException sEx = ( SQLException ) e;
                log.error( "SQL State : " + sEx.getSQLState() );
                log.error( "SQL ErrorCode : " + sEx.getErrorCode() );
                log.error( "SQL异常 : ", e );

            }
            throw new DataAccessException( "Exception : ", e );
        }
        finally
        {
            TransactionState transactionState = ( TransactionState ) threadInfoHolder.get();
            if( transactionState != null )
            {
                Map pStmtMap = transactionState.getBatchModeStmt();
                if( pStmtMap != null )
                {
                    /**
                     * 关闭批处理statement
                     */
                    Iterator psIt = pStmtMap.values().iterator();
                    while ( psIt.hasNext() )
                    {
                        JdbcInstrument.closeStatement( ( PreparedStatement ) psIt.next() );
                    }
                }
            }

            JdbcInstrument.closeConnection( connection );
            tranConnectionHolder.set( null );
            threadInfoHolder.set( null );
        }
    }

    /**
     * 提示数据库是否只读模式
     * 
     * @param readOnly
     * 
     */
    @SuppressWarnings( "unchecked" )
    public void setReadOnly( boolean readOnly )
    {
        Connection connection = getConnectionInTransactionScene();
        boolean closeSucc = false;

        try
        {
            connection.setReadOnly( readOnly );
        }
        catch ( SQLException e )
        {
            closeSucc = JdbcInstrument.closeConnection( connection );
            tranConnectionHolder.set( null );
            threadInfoHolder.set( null );
            if( closeSucc )
            {
                connection = null;
            }
            throw new DataAccessException( e );
        }
        catch ( Exception e )
        {
            closeSucc = JdbcInstrument.closeConnection( connection );
            tranConnectionHolder.set( null );
            threadInfoHolder.set( null );
            if( closeSucc )
            {
                connection = null;
            }
            throw new DataAccessException( "未知异常", e );
        }
        finally
        {
            if( closeSucc )
            {
                JdbcInstrument.closeConnection( connection );
            }
        }

    }

    /**
     * @deprecated 暂时无实现，此方法废弃。
     */

    public void rollbackTransaction( String savePoint ) throws DataAccessException
    {
        Connection connection = getConnectionInTransactionScene();

        try
        {
            connection.rollback( null );
            JdbcInstrument.closeConnection( connection );
            tranConnectionHolder.set( null );
        }
        catch ( SQLException e )
        {
            JdbcInstrument.closeConnection( connection );
            tranConnectionHolder.set( null );
            throw new DataAccessException( e );
        }
        catch ( Exception e )
        {
            JdbcInstrument.closeConnection( connection );
            tranConnectionHolder.set( null );
            throw new DataAccessException( "未知异常", e );
        }
        finally
        {
            JdbcInstrument.closeConnection( connection );
        }
    }

    /**
     * 对一次事务进行最后的合理的处理。对任何错误引起的没有正常提交情况都会尝试回滚并且释放相关资源<br>
     * 其原则是:只要当前事务信息中还存在着任何需要清除的资源,立即尝试清除动作.而不管何种原因导致资源存在,以保证<br>
     * 事务之间不产生冲突.
     * 
     * @throws DataAccessException
     * 
     */
    public void endTransaction()
    {
        log.info( "[End Transaction] : 获取线程资源" );

        Connection connection = ( Connection ) tranConnectionHolder.get();
        TransactionState transactionState = ( TransactionState ) threadInfoHolder.get();

        Exception exception = null;
        /**
         * 当前流程仍处于事务流程中，根据事务状态处理相关资源
         */
        if( transactionState != null )//
        {
            log.info( "isCommitExceptionOccur : " + transactionState.exceptionFlag
                + ", isTransactionOver : " + transactionState.isTransactionOver() );

            /**
             * 如果由于某种情况事务没有正常结束,需要在这里回滚
             */
            if( ( !transactionState.isTransactionOver() ) || ( transactionState.isExceptionOccur() ) )
            {

                try
                {
                    if( connection == null )
                    {
                        throw new CannotGetConnectionException( "Connection对象不存在，无法执行回滚操作！" );
                    }
                    else
                    {
                        connection.rollback();
                        log.info( "[End Transaction] : Rollback......" );
                    }

                    /**
                     * 释放回滚后的资源
                     */
                }
                catch ( Exception e )
                {
                    exception = e;
                }
            }

            log.info( "[End Transaction] ：数据库资源最终释放 #### 开始 ####" );

            // 关闭一般事务statement
            Map txStmtMap = transactionState.getTransactionModeStmt();
            if( txStmtMap != null )
            {
                clearAllTxStmt( txStmtMap );
                log.info( "[End Transaction] ：一般事务资源释放......" );
            }

            // 关闭Key模式statement
            Map txKeyStmtMap = transactionState.getTransactionKeyModeStmt();
            if( txKeyStmtMap != null )
            {
                clearAllTxStmt( txKeyStmtMap );
                log.info( "[End Transaction] ：Key模式事务资源释放......" );
            }

            // 关闭批处理statement
            Map pStmtMap = transactionState.getBatchModeStmt();
            if( pStmtMap != null )
            {
                clearAllTxStmt( pStmtMap );
                log.info( "[End Transaction] ：批处理资源释放......" );
            }

            threadInfoHolder.set( null );
            log.info( "[End Transaction] ：线程资源释放......" );
        }

        setToAutoCommitState( connection );
        JdbcInstrument.closeConnection( connection );

        if( connection != null )
        {
            tranConnectionHolder.set( null );
            log.info( "[End Transaction] ：connection资源释放......" );
        }

        if( exception != null )
        {
            if( exception instanceof SQLException )
            {
                SQLException sEx = ( SQLException ) exception;
                log.error( "SQL State : " + sEx.getSQLState() );
                log.error( "SQL ErrorCode : " + sEx.getErrorCode() );
                log.error( "SQL异常 : ", exception );

            }

            if( exception instanceof DataAccessException )
            {
                DataAccessException daEx = ( DataAccessException ) exception;
                throw daEx;
            }
            throw new DataAccessException( "Exception : ", exception );
        }

        log.info( "[End Transaction] ：数据库资源释放完成 #### 结束 ####" );

    }

    /**
     * 
     * 启动批量更新方式执行非查询sql
     * 
     */
    public void startBatch()
    {
        TransactionState txState = getTransactionState();
        txState.setBatchUpdateMode( BATCH_BEGIN );// 启动批量处理模式
        txState.setBatchModeStmt( new HashMap() );
        log.info( "[批处理更新模式]  ...开始..." );
    }

    /**
     * 执行批处理更新
     * 
     * @return
     * @throws SQLException
     * 
     */
    public List executeBatch()
    {
        // 用来记录更新了多少数据
        List upRow = null;
        TransactionState txState = getTransactionState();
        Map batchStatementMap = txState.getBatchModeStmt();

        try
        {
            if( batchStatementMap != null )
            {
                upRow = new ArrayList();
                Iterator stmtIt = batchStatementMap.values().iterator();
                while ( stmtIt.hasNext() )
                {
                    PreparedStatement batchStmt = ( PreparedStatement ) stmtIt.next();
                    System.out.println( "########################" );
                    upRow.add( batchStmt.executeBatch() );
                    batchStmt.clearBatch();
                    /**
                     * 不可在这里关闭Statement,只需要clear
                     */
                }
            }
        }
        catch ( Exception e )
        {
            if( txState != null )
            {
                txState.setTransactionOver( TRANSACTION_FAIL );
            }

            if( batchStatementMap != null )
            {
                Iterator stmtIt = batchStatementMap.values().iterator();
                while ( stmtIt.hasNext() )
                {
                    JdbcInstrument.closeStatement( ( PreparedStatement ) stmtIt.next() );
                }
            }

            if( e instanceof SQLException )
            {
                SQLException sEx = ( SQLException ) e;
                log.error( "SQL State : " + sEx.getSQLState() );
                log.error( "SQL ErrorCode : " + sEx.getErrorCode() );
                log.error( "SQL异常 : ", e );

            }

            if( e instanceof DataAccessException )
            {
                DataAccessException daEx = ( DataAccessException ) e;
                throw daEx;
            }

            txState.setBatchUpdateMode( BATCH_END );
            throw new DataAccessException( "executeBatch exception : ", e );

        }

        txState.setBatchUpdateMode( BATCH_END );
        log.info( "[批处理更新模式]  ...执行完毕..." );
        return upRow;
    }

    /**
     * 在非事务状态下启动共享Connection数据操作方式，改方法调用后，同线程中的数据库操作将会<br>
     * 使用同一Connection对象。
     * 
     * @throws DataAccessException
     */
    public void shareConnection() throws DataAccessException
    {
        boolean closeSucc;

        /**
         * 若调用此方法时线程中存在事务状态，说明当前数据操作已经在事务环境下
         */
        if( threadInfoHolder.get() != null )
        {
            threadInfoHolder.set( null );
            tranConnectionHolder.set( null );
            throw new DataAccessException( "当前线程已存在数据库事务操作状态，共享Connection对象失败。" );
        }

        Connection connection = ( Connection ) shareConnectionHolder.get();

        /**
         * 如果当前共享容器已经有了Connection,那么意味着当前在重复共享COnnection,<br>
         * 或有其他情况导致当前处理线程有未知connection存在在共享容器中
         */
        if( connection != null )
        {
            // 关闭已存在的Connection并清空线程
            closeSucc = JdbcInstrument.closeConnection( connection );
            shareConnectionHolder.set( null );
            if( closeSucc )
            {
                connection = null;
            }
            throw new DataAccessException( "当前线程已存在未知Connection,共享失败。" );
        }

        connection = openConnection();
        shareConnectionHolder.set( connection );

        log.info( "共享数据库连接模式 [开始]" );
    }

    /**
     * 停止共享Connection并回收。
     * 
     * @throws DataAccessException
     */
    public void endShareConnection() throws DataAccessException
    {
        boolean closeSucc = false;

        Connection connection = ( Connection ) shareConnectionHolder.get();

        if( connection == null )
        {
            throw new DataAccessException( "当前线程没有共享连接或共享Connection丢失" );
        }

        closeSucc = JdbcInstrument.closeConnection( connection );
        shareConnectionHolder.set( null );
        if( closeSucc )
        {
            connection = null;
        }

        log.info( "共享数据库连接模式 [结束]" );
    }

    public static void registerSQL( Object pojo )
    {
        if( pojo == null )
        {
            throw new NullPointerException();
        }

        // if( !( pojo instanceof TableInfomationProvider ) )
        // {
        // throw new ClassCastException( "目标持久层对象必须为TableInfomationProvider类型"
        // );
        // }

        entitySqlMap.put( pojo.getClass().getName(), new EntitySqlBridge( pojo ) );
    }

    public static EntitySqlBridge getEntitySql( Class<?> clazz )
    {
        if( clazz == null )
        {
            throw new NullPointerException( "必须指定实体类型信息" );
        }

        EntitySqlBridge entitySql = ( EntitySqlBridge ) entitySqlMap.get( clazz.getName() );

        if( entitySql == null )// sql缓存中不存在信息，那么需要注册静态sql
        {
            try
            {
                entitySql = new EntitySqlBridge( ObjectUtility.buildObject( clazz ) );

                entitySqlMap.put( clazz.getName(), entitySql );

                return entitySql;
            }
            catch ( Exception e )
            {
                log.error( e );
                throw new DataAccessException( e );
            }
        }

        return entitySql;
    }

    private Connection getConnectionInTransactionScene() throws DataAccessException
    {
        Connection connection = ( Connection ) tranConnectionHolder.get();
        if( connection == null )
        {
            log.error( "当前更新操作无法从当前系统环境获取连接" );
            throw new CannotGetConnectionException( "事务关联的Connetion对象不存在或被关闭" );
        }
        return connection;

    }

    private TransactionState getTransactionState()
    {
        TransactionState transactionState = ( TransactionState ) threadInfoHolder.get();
        if( transactionState == null )
        {
            throw new DataAccessException( "事务状态不存在被关闭" );
        }
        return transactionState;

    }

    /**
     * 记录一次事务中的相关状态
     * 
     * @author mjsoft
     * 
     */
    private static final class TransactionState
    {
        /**
         * 异常发生标志
         */
        private boolean exceptionFlag = false;

        /**
         * 这次事务提交了吗（任何没有提交的事务都将回滚）
         */
        private boolean transactionOver = false;

        /**
         * 是否批处理更新模式
         */
        private boolean batchUpdateMode = false;

        /**
         * 批处理相关的PreparedStatement
         */
        private Map batchModeStmt = null;

        /**
         * 一般事务相关的PreparedStatement
         */
        private Map transactionModeStmt = null;

        /**
         * 一般事务更新相关的PreparedStatement(返回Key模式)
         */
        private Map transactionKeyModeStmt = null;

        //
        // /**
        // * 是否是第一次的PreparedStatement
        // */
        // private boolean isFirstStmt = false;

        public boolean isExceptionOccur()
        {
            return exceptionFlag;
        }

        public void setExceptionOccur( boolean isExceptionOccur )
        {
            this.exceptionFlag = isExceptionOccur;
        }

        public boolean isTransactionOver()
        {
            return transactionOver;
        }

        public void setTransactionOver( boolean transactionOver )
        {
            this.transactionOver = transactionOver;
        }

        public boolean isBatchUpdateMode()
        {
            return batchUpdateMode;
        }

        public void setBatchUpdateMode( boolean batchUpdateMode )
        {
            this.batchUpdateMode = batchUpdateMode;
        }

        public Map getBatchModeStmt()
        {
            return batchModeStmt;
        }

        public void setBatchModeStmt( Map batchStmt )
        {
            this.batchModeStmt = batchStmt;
        }

        public Map getTransactionModeStmt()
        {
            return transactionModeStmt;
        }

        public void setTransactionModeStmt( Map transactionStmt )
        {
            this.transactionModeStmt = transactionStmt;
        }

        public Map getTransactionKeyModeStmt()
        {
            return transactionKeyModeStmt;
        }

        public void setTransactionKeyModeStmt( Map transactionKeyModeStmt )
        {
            this.transactionKeyModeStmt = transactionKeyModeStmt;
        }
    }

    private Object[] getAllInsertParamValue( Object pojo, int paramCount )
    {
        Object[] params = new Object[paramCount];

        int incFlag = 0;

        EntitySqlBridge entitySql = getEntitySql( pojo.getClass() );

        Iterator fieldNameIter = entitySql.getFieldNameIterator();
        while ( fieldNameIter.hasNext() )
        {
            String name = ( String ) fieldNameIter.next();
            Field fe = entitySql.getPojoSqlField( name );

            log.debug( "IdMode : " + entitySql.getIdMode() + " : fieldName : " + name );

            // 若主键值由程序负责创建的情况
            if( EntitySqlBridge.ASSIGNED == entitySql.getIdMode() )
            {
                params[incFlag++] = ObjectUtility.getPrivateFieldValue( fe, pojo );
            }
            // 以下情况意味着由数据库帮我们生成，需要跳过id字段,只设置非id字段的值
            // ，由于paramCount的大小会由主键生成方式影响，所以params的大小绝对会是对的
            else if( !entitySql.getIdentification().equals( name ) )
            {
                params[incFlag++] = ObjectUtility.getPrivateFieldValue( fe, pojo );
            }

        }

        return params;
    }

    private Object[] getAllUpdateParamValue( Object pojo, int paramCount )
    {
        Object[] params = new Object[paramCount];

        int incFlag = 0;

        EntitySqlBridge entitySql = PersistenceEngine.getEntitySql( pojo.getClass() );

        Iterator fieldNameIter = entitySql.getFieldNameIterator();
        while ( fieldNameIter.hasNext() )
        {
            String name = ( String ) fieldNameIter.next();
            Field fe = entitySql.getPojoSqlField( name );
            // 组装参数，id作为where条件放在最后
            if( entitySql.getIdentification().equals( name ) )
            {
                params[paramCount - 1] = ObjectUtility.getPrivateFieldValue( fe, pojo );
            }
            else
            {// 一般的参数组装
                params[incFlag++] = ObjectUtility.getPrivateFieldValue( fe, pojo );
            }
        }

        return params;
    }

    private Object getIdParamValue( Object pojo )
    {
        EntitySqlBridge entitySql = getEntitySql( pojo.getClass() );

        Field idField = entitySql.getPojoSqlField( entitySql.getIdentification() );

        return ObjectUtility.getPrivateFieldValue( idField, pojo );
    }

    private void setToAutoCommitState( Connection conn )
    {
        if( conn != null )
        {
            try
            {
                if( !conn.isClosed() )
                {
                    conn.setAutoCommit( AUTO_COMMIT );
                }
                log.debug( "设定为自动提交模式" );
            }
            catch ( SQLException sEx )
            {
                log.error( "SQL State : " + sEx.getSQLState() );
                log.error( "SQL ErrorCode : " + sEx.getErrorCode() );
                log.error( "SQL异常 : ", sEx );

            }
        }

    }

    private void clearAllTxStmt( Map stmtMap )
    {
        Iterator psIt = stmtMap.values().iterator();
        while ( psIt.hasNext() )
        {
            JdbcInstrument.closeStatement( ( PreparedStatement ) psIt.next() );
        }

        log.info( "[commit] ：TX STMT 资源释放......" );
    }

}
